package view;

import graphics.complexe.NodeGraphicObject;
import graphics.engine.ProgramShader;
import graphics.primitive.Polyline;

import java.util.ArrayList;
import java.util.Iterator;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;

import settings.Settings;
import utils.Point3D;
import utils.Vector3D;
import colors.Color;

import mathematics.geometry.Geometry;
import mathematics.geometry.PolylineGeometry;
import matrix.GraphLink;
import matrix.GraphNode;
import matrix.GraphNodeType;
import matrix.NodeLinkMatrix;

public class GraphView 
{
	private NodeLinkMatrix model;
	private static final float nodeSize = Settings.InnerGraphNodeSize;
	
	public ArrayList<NodeGraphicObject> nodesGraphics;
	public ArrayList<Polyline> linkGraphics;
	
	
	public GraphView(GL gl, NodeLinkMatrix matrix)
	{
		this.model = matrix;
		this.nodesGraphics = new ArrayList<NodeGraphicObject>();
		this.linkGraphics = new ArrayList<Polyline>();
		if(this.model != null)
		{
			for(Iterator<GraphNode> it = this.model.getKeys().iterator(); it.hasNext();)
			{
				GraphNode checkpoint = it.next();
				
				NodeGraphicObject node = new NodeGraphicObject(gl);
				node.setPosition(new Point3D(checkpoint.getPosition().x(), checkpoint.getPosition().y(), 0.0f));
				node.setScale(new Vector3D(nodeSize, nodeSize , nodeSize));	
				if(Settings.DebugInnerGraph)
				{
					if(checkpoint.getType() == GraphNodeType.CheckPoint)
					{
						node.setBaseColor(new Color(1.0f, 0.0f, 0.0f, 1.0f));
					}
					else if(checkpoint.getType() == GraphNodeType.InterestPoint)
					{
						node.setBaseColor(new Color(0.0f, 1.0f, 0.0f, 1.0f));
					}
					else
					{
						node.setBaseColor(new Color(0.0f, 0.0f, 1.0f, 1.0f));	
					}
				}
				else
				{
					node.setBaseColor(new Color(1.0f, 1.0f, 1.0f));
				}
				node.setOutlineColor(new Color(0.0f, 0.0f, 0.0f, 1.0f));
		
				this.nodesGraphics.add(node);
			}
			
			for(int row = 0; row < this.model.getSize(); row++)
			{
				for(int col = row; col < this.model.getSize(); col++ )
				{
					ArrayList<GraphLink> links = this.model.get(row, col);
					if(!links.isEmpty())
					{
						GraphLink link = (GraphLink) links.get(0);
						ArrayList<Point3D> linePoints = new ArrayList<Point3D>();
						linePoints.add(link.getFirstNode().getPosition());
						linePoints.add(link.getSecondNode().getPosition());
						Geometry geometry = new PolylineGeometry(linePoints);
						geometry.setLoop(false);
						Polyline line = new Polyline(gl, geometry, 1.0f);
						this.linkGraphics.add(line);
					}
				}
			}
		}
	}


	public void Draw(GLAutoDrawable drawable, ProgramShader programShader) {
		// TODO Auto-generated method stub
		for(Iterator<Polyline> it = this.linkGraphics.iterator(); it.hasNext();)
		{
			Polyline line = it.next();
			line.Draw(drawable, programShader);
		}
		
		for(Iterator<NodeGraphicObject> it = this.nodesGraphics.iterator(); it.hasNext();)
		{
			NodeGraphicObject node = it.next();
			node.Draw(drawable, programShader);
		}
	}
	
}
